home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_perl.idb / usr / freeware / catman / u_man / cat1 / perldsc.Z / perldsc
Encoding:
Text File  |  1998-10-28  |  36.3 KB  |  1,189 lines

  1.  
  2.  
  3.  
  4.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  5.  
  6.  
  7.  
  8.      NNNNAAAAMMMMEEEE
  9.       perldsc - Perl Data Structures Cookbook
  10.  
  11.      DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
  12.       The single feature most sorely lacking in the    Perl
  13.       programming language prior to    its 5.0    release    was complex
  14.       data structures.  Even without direct    language support, some
  15.       valiant programmers did manage to emulate them, but it was
  16.       hard work and    not for    the faint of heart.  You could
  17.       occasionally get away    with the $m{$LoL,$b} notation borrowed
  18.       from _a_w_k in which the    keys are actually more like a single
  19.       concatenated string "$LoL$b",    but traversal and sorting were
  20.       difficult.  More desperate programmers even hacked Perl's
  21.       internal symbol table    directly, a strategy that proved hard
  22.       to develop and maintain--to put it mildly.
  23.  
  24.       The 5.0 release of Perl let us have complex data structures.
  25.       You may now write something like this    and all    of a sudden,
  26.       you'd    have a array with three    dimensions!
  27.  
  28.           for $x (1    .. 10) {
  29.           for $y (1 .. 10) {
  30.               for $z (1    .. 10) {
  31.               $LoL[$x][$y][$z] =
  32.                   $x ** $y + $z;
  33.               }
  34.           }
  35.           }
  36.  
  37.       Alas,    however    simple this may    appear,    underneath it's    a much
  38.       more elaborate construct than    meets the eye!
  39.  
  40.       How do you print it out?  Why    can't you say just print @LoL?
  41.       How do you sort it?  How can you pass    it to a    function or
  42.       get one of these back    from a function?  Is is    an object?
  43.       Can you save it to disk to read back later?  How do you
  44.       access whole rows or columns of that matrix?    Do all the
  45.       values have to be numeric?
  46.  
  47.       As you see, it's quite easy to become    confused.  While some
  48.       small    portion    of the blame for this can be attributed    to the
  49.       reference-based implementation, it's really more due to a
  50.       lack of existing documentation with examples designed    for
  51.       the beginner.
  52.  
  53.       This document    is meant to be a detailed but understandable
  54.       treatment of the many    different sorts    of data    structures you
  55.       might    want to    develop.  It should also serve as a cookbook
  56.       of examples.    That way, when you need    to create one of these
  57.       complex data structures, you can just    pinch, pilfer, or
  58.       purloin a drop-in example from here.
  59.  
  60.  
  61.  
  62.  
  63.      Page 1                        (printed 10/23/98)
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  71.  
  72.  
  73.  
  74.       Let's    look at    each of    these possible constructs in detail.
  75.       There    are separate sections on each of the following:
  76.  
  77.       +o arrays of arrays
  78.  
  79.       +o hashes of arrays
  80.  
  81.       +o arrays of hashes
  82.  
  83.       +o hashes of hashes
  84.  
  85.       +o more elaborate constructs
  86.  
  87.       But for now, let's look at general issues common to all
  88.       these    types of data structures.
  89.  
  90.      RRRREEEEFFFFEEEERRRREEEENNNNCCCCEEEESSSS
  91.       The most important thing to understand about all data
  92.       structures in    Perl --    including multidimensional arrays--is
  93.       that even though they    might appear otherwise,    Perl @ARRAYs
  94.       and %HASHes are all internally one-dimensional.  They    can
  95.       hold only scalar values (meaning a string, number, or    a
  96.       reference).  They cannot directly contain other arrays or
  97.       hashes, but instead contain _r_e_f_e_r_e_n_c_e_s to other arrays or
  98.       hashes.
  99.  
  100.       You can't use    a reference to a array or hash in quite    the
  101.       same way that    you would a real array or hash.     For C or C++
  102.       programmers unused to    distinguishing between arrays and
  103.       pointers to the same,    this can be confusing.    If so, just
  104.       think    of it as the difference    between    a structure and    a
  105.       pointer to a structure.
  106.  
  107.       You can (and should) read more about references in the
  108.       _p_e_r_l_r_e_f(1) man page.    Briefly, references are    rather like
  109.       pointers that    know what they point to.  (Objects are also a
  110.       kind of reference, but we won't be needing them right
  111.       away--if ever.)  This    means that when    you have something
  112.       which    looks to you like an access to a two-or-more-
  113.       dimensional array and/or hash, what's    really going on    is
  114.       that the base    type is    merely a one-dimensional entity    that
  115.       contains references to the next level.  It's just that you
  116.       can _u_s_e it as    though it were a two-dimensional one.  This is
  117.       actually the way almost all C    multidimensional arrays    work
  118.       as well.
  119.  
  120.           $list[7][12]              # array of arrays
  121.           $list[7]{string}              # array of hashes
  122.           $hash{string}[7]              # hash of arrays
  123.           $hash{string}{'another string'}      # hash of hashes
  124.  
  125.       Now, because the top level contains only references, if you
  126.  
  127.  
  128.  
  129.      Page 2                        (printed 10/23/98)
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  137.  
  138.  
  139.  
  140.       try to print out your    array in with a    simple _p_r_i_n_t()
  141.       function, you'll get something that doesn't look very    nice,
  142.       like this:
  143.  
  144.           @LoL = ( [2, 3], [4, 5, 7], [0] );
  145.           print $LoL[1][2];
  146.         7
  147.           print @LoL;
  148.         ARRAY(0x83c38)ARRAY(0x8b194)ARRAY(0x8b1d0)
  149.  
  150.       That's because Perl doesn't (ever) implicitly    dereference
  151.       your variables.  If you want to get at the thing a reference
  152.       is referring to, then    you have to do this yourself using
  153.       either prefix    typing indicators, like    ${$blah}, @{$blah},
  154.       @{$blah[$i]},    or else    postfix    pointer    arrows,    like $a->[3],
  155.       $h->{fred}, or even $ob->method()->[3].
  156.  
  157.      CCCCOOOOMMMMMMMMOOOONNNN MMMMIIIISSSSTTTTAAAAKKKKEEEESSSS
  158.       The two most common mistakes made in constructing something
  159.       like an array    of arrays is either accidentally counting the
  160.       number of elements or    else taking a reference    to the same
  161.       memory location repeatedly.  Here's the case where you just
  162.       get the count    instead    of a nested array:
  163.  
  164.           for $i (1..10) {
  165.           @list    = somefunc($i);
  166.           $LoL[$i] = @list;      # WRONG!
  167.           }
  168.  
  169.       That's just the simple case of assigning a list to a scalar
  170.       and getting its element count.  If that's what you really
  171.       and truly want, then you might do well to consider being a
  172.       tad more explicit about it, like this:
  173.  
  174.           for $i (1..10) {
  175.           @list    = somefunc($i);
  176.           $counts[$i] =    scalar @list;
  177.           }
  178.  
  179.       Here's the case of taking a reference    to the same memory
  180.       location again and again:
  181.  
  182.           for $i (1..10) {
  183.           @list    = somefunc($i);
  184.           $LoL[$i] = \@list;      # WRONG!
  185.           }
  186.  
  187.       So, what's the big problem with that?     It looks right,
  188.       doesn't it?  After all, I just told you that you need    an
  189.       array    of references, so by golly, you've made    me one!
  190.  
  191.       Unfortunately, while this is true, it's still    broken.     All
  192.  
  193.  
  194.  
  195.      Page 3                        (printed 10/23/98)
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  203.  
  204.  
  205.  
  206.       the references in @LoL refer to the _v_e_r_y _s_a_m_e    _p_l_a_c_e, and
  207.       they will therefore all hold whatever    was last in @list!
  208.       It's similar to the problem demonstrated in the following C
  209.       program:
  210.  
  211.           #include <pwd.h>
  212.           main() {
  213.           struct passwd    *getpwnam(), *rp, *dp;
  214.           rp = getpwnam("root");
  215.           dp = getpwnam("daemon");
  216.  
  217.           printf("daemon name is %s\nroot name is %s\n",
  218.               dp->pw_name, rp->pw_name);
  219.           }
  220.  
  221.       Which    will print
  222.  
  223.           daemon name is daemon
  224.           root name    is daemon
  225.  
  226.       The problem is that both rp and dp are pointers to the same
  227.       location in memory!  In C, you'd have    to remember to
  228.       _m_a_l_l_o_c() yourself some new memory.  In Perl, you'll want to
  229.       use the array    constructor [] or the hash constructor {}
  230.       instead.   Here's the    right way to do    the preceding broken
  231.       code fragments:
  232.  
  233.           for $i (1..10) {
  234.           @list    = somefunc($i);
  235.           $LoL[$i] = [ @list ];
  236.           }
  237.  
  238.       The square brackets make a reference to a new    array with a
  239.       _c_o_p_y of what's in @list at the time of the assignment.  This
  240.       is what you want.
  241.  
  242.       Note that this will produce something    similar, but it's much
  243.       harder to read:
  244.  
  245.           for $i (1..10) {
  246.           @list    = 0 .. $i;
  247.           @{$LoL[$i]} =    @list;
  248.           }
  249.  
  250.       Is it    the same?  Well, maybe so--and maybe not.  The subtle
  251.       difference is    that when you assign something in square
  252.       brackets, you    know for sure it's always a brand new
  253.       reference with a new _c_o_p_y of the data.  Something else could
  254.       be going on in this new case with the    @{$LoL[$i]}}
  255.       dereference on the left-hand-side of the assignment.    It all
  256.       depends on whether $LoL[$i] had been undefined to start
  257.       with,    or whether it already contained    a reference.  If you
  258.  
  259.  
  260.  
  261.      Page 4                        (printed 10/23/98)
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  269.  
  270.  
  271.  
  272.       had already populated    @LoL with references, as in
  273.  
  274.           $LoL[3] =    \@another_list;
  275.  
  276.       Then the assignment with the indirection on the left-hand-
  277.       side would use the existing reference    that was already
  278.       there:
  279.  
  280.           @{$LoL[3]} = @list;
  281.  
  282.       Of course, this _w_o_u_l_d    have the "interesting" effect of
  283.       clobbering @another_list.  (Have you ever noticed how    when a
  284.       programmer says something is "interesting", that rather than
  285.       meaning "intriguing",    they're    disturbingly more apt to mean
  286.       that it's "annoying",    "difficult", or    both?  :-)
  287.  
  288.       So just remember always to use the array or hash
  289.       constructors with [] or {}, and you'll be fine, although
  290.       it's not always optimally efficient.
  291.  
  292.       Surprisingly,    the following dangerous-looking    construct will
  293.       actually work    out fine:
  294.  
  295.           for $i (1..10) {
  296.           my @list = somefunc($i);
  297.           $LoL[$i] = \@list;
  298.           }
  299.  
  300.       That's because _m_y() is more of a run-time statement than it
  301.       is a compile-time declaration    _p_e_r _s_e.     This means that the
  302.       _m_y() variable    is remade afresh each time through the loop.
  303.       So even though it _l_o_o_k_s as though you    stored the same
  304.       variable reference each time,    you actually did not!  This is
  305.       a subtle distinction that can    produce    more efficient code at
  306.       the risk of misleading all but the most experienced of
  307.       programmers.    So I usually advise against teaching it    to
  308.       beginners.  In fact, except for passing arguments to
  309.       functions, I seldom like to see the gimme-a-reference
  310.       operator (backslash) used much at all    in code.  Instead, I
  311.       advise beginners that    they (and most of the rest of us)
  312.       should try to    use the    much more easily understood
  313.       constructors [] and {} instead of relying upon lexical (or
  314.       dynamic) scoping and hidden reference-counting to do the
  315.       right    thing behind the scenes.
  316.  
  317.       In summary:
  318.  
  319.           $LoL[$i] = [ @list ];      # usually best
  320.           $LoL[$i] = \@list;      # perilous; just how my() was    that list?
  321.           @{ $LoL[$i] } = @list;      # way    too tricky for most programmers
  322.  
  323.  
  324.  
  325.  
  326.  
  327.      Page 5                        (printed 10/23/98)
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  335.  
  336.  
  337.  
  338.      CCCCAAAAVVVVEEEEAAAATTTT OOOONNNN PPPPRRRREEEECCCCEEEEDDDDEEEENNNNCCCCEEEE
  339.       Speaking of things like @{$LoL[$i]}, the following are
  340.       actually the same thing:
  341.  
  342.           $listref->[2][2]      # clear
  343.           $$listref[2][2]      # confusing
  344.  
  345.       That's because Perl's    precedence rules on its    five prefix
  346.       dereferencers    (which look like someone swearing: $ @ * % &)
  347.       make them bind more tightly than the postfix subscripting
  348.       brackets or braces!  This will no doubt come as a great
  349.       shock    to the C or C++    programmer, who    is quite accustomed to
  350.       using    *a[i] to mean what's pointed to    by the _i'_t_h element of
  351.       a.  That is, they first take the subscript, and only then
  352.       dereference the thing    at that    subscript.  That's fine    in C,
  353.       but this isn't C.
  354.  
  355.       The seemingly    equivalent construct in    Perl, $$listref[$i]
  356.       first    does the deref of $listref, making it take $listref as
  357.       a reference to an array, and then dereference    that, and
  358.       finally tell you the _i'_t_h value of the array pointed to by
  359.       $LoL.    If you wanted the C notion, you'd have to write
  360.       ${$LoL[$i]} to force the $LoL[$i] to get evaluated first
  361.       before the leading $ dereferencer.
  362.  
  363.      WWWWHHHHYYYY YYYYOOOOUUUU SSSSHHHHOOOOUUUULLLLDDDD AAAALLLLWWWWAAAAYYYYSSSS uuuusssseeee ssssttttrrrriiiicccctttt
  364.       If this is starting to sound scarier than it's worth,    relax.
  365.       Perl has some    features to help you avoid its most common
  366.       pitfalls.  The best way to avoid getting confused is to
  367.       start    every program like this:
  368.  
  369.           #!/usr/bin/perl -w
  370.           use strict;
  371.  
  372.       This way, you'll be forced to    declare    all your variables
  373.       with _m_y() and    also disallow accidental "symbolic
  374.       dereferencing".  Therefore if    you'd done this:
  375.  
  376.           my $listref = [
  377.           [ "fred", "barney", "pebbles", "bambam", "dino", ],
  378.           [ "homer", "bart", "marge", "maggie",    ],
  379.           [ "george", "jane", "elroy", "judy", ],
  380.           ];
  381.  
  382.           print $listref[2][2];
  383.  
  384.       The compiler would immediately flag that as an error _a_t
  385.       _c_o_m_p_i_l_e _t_i_m_e,    because    you were accidentally accessing
  386.       @listref, an undeclared variable, and    it would thereby
  387.       remind you to    write instead:
  388.  
  389.           print $listref->[2][2]
  390.  
  391.  
  392.  
  393.      Page 6                        (printed 10/23/98)
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  401.  
  402.  
  403.  
  404.      DDDDEEEEBBBBUUUUGGGGGGGGIIIINNNNGGGG
  405.       Before version 5.002,    the standard Perl debugger didn't do a
  406.       very nice job    of printing out    complex    data structures.  With
  407.       5.002    or above, the debugger includes    several    new features,
  408.       including command line editing as well as the    x command to
  409.       dump out complex data    structures.  For example, given    the
  410.       assignment to    $LoL above, here's the debugger    output:
  411.  
  412.           DB<1> x $LoL
  413.           $LoL = ARRAY(0x13b5a0)
  414.          0  ARRAY(0x1f0a24)
  415.             0  'fred'
  416.             1  'barney'
  417.             2  'pebbles'
  418.             3  'bambam'
  419.             4  'dino'
  420.          1  ARRAY(0x13b558)
  421.             0  'homer'
  422.             1  'bart'
  423.             2  'marge'
  424.             3  'maggie'
  425.          2  ARRAY(0x13b540)
  426.             0  'george'
  427.             1  'jane'
  428.             2  'elroy'
  429.             3  'judy'
  430.  
  431.  
  432.      CCCCOOOODDDDEEEE EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
  433.       Presented with little    comment    (these will get    their own
  434.       manpages someday) here are short code    examples illustrating
  435.       access of various types of data structures.
  436.  
  437.      LLLLIIIISSSSTTTTSSSS OOOOFFFF LLLLIIIISSSSTTTTSSSS
  438.       DDDDeeeeccccllllaaaarrrraaaattttiiiioooonnnn ooooffff aaaa LLLLIIIISSSSTTTT    OOOOFFFF LLLLIIIISSSSTTTTSSSS
  439.  
  440.        @LoL    = (
  441.           [ "fred", "barney" ],
  442.           [ "george", "jane", "elroy" ],
  443.           [ "homer", "marge", "bart" ],
  444.         );
  445.  
  446.  
  447.       GGGGeeeennnneeeerrrraaaattttiiiioooonnnn ooooffff    aaaa LLLLIIIISSSSTTTT OOOOFFFF LLLLIIIISSSSTTTTSSSS
  448.  
  449.        # reading from file
  450.        while ( <> )    {
  451.            push @LoL, [ split ];
  452.        }
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.      Page 7                        (printed 10/23/98)
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  467.  
  468.  
  469.  
  470.        # calling a function
  471.        for $i ( 1 .. 10 ) {
  472.            $LoL[$i]    = [ somefunc($i) ];
  473.        }
  474.  
  475.        # using temp    vars
  476.        for $i ( 1 .. 10 ) {
  477.            @tmp = somefunc($i);
  478.            $LoL[$i]    = [ @tmp ];
  479.        }
  480.  
  481.        # add to an existing    row
  482.        push    @{ $LoL[0] }, "wilma", "betty";
  483.  
  484.  
  485.       AAAAcccccccceeeessssssss aaaannnndddd PPPPrrrriiiinnnnttttiiiinnnngggg ooooffff aaaa LLLLIIIISSSSTTTT    OOOOFFFF LLLLIIIISSSSTTTTSSSS
  486.  
  487.        # one element
  488.        $LoL[0][0] =    "Fred";
  489.  
  490.        # another element
  491.        $LoL[1][1] =~ s/(\w)/\u$1/;
  492.  
  493.        # print the whole thing with    refs
  494.        for $aref ( @LoL ) {
  495.            print "\t [ @$aref ],\n";
  496.        }
  497.  
  498.        # print the whole thing with    indices
  499.        for $i ( 0 .. $#LoL ) {
  500.            print "\t [ @{$LoL[$i]} ],\n";
  501.        }
  502.  
  503.        # print the whole thing one at a time
  504.        for $i ( 0 .. $#LoL ) {
  505.            for $j (    0 .. $#{ $LoL[$i] } ) {
  506.            print "elt $i $j is $LoL[$i][$j]\n";
  507.            }
  508.        }
  509.  
  510.  
  511.      HHHHAAAASSSSHHHHEEEESSSS OOOOFFFF LLLLIIIISSSSTTTTSSSS
  512.       DDDDeeeeccccllllaaaarrrraaaattttiiiioooonnnn ooooffff aaaa HHHHAAAASSSSHHHH    OOOOFFFF LLLLIIIISSSSTTTTSSSS
  513.  
  514.        %HoL    = (
  515.           flintstones         =>    [ "fred", "barney" ],
  516.           jetsons         =>    [ "george", "jane", "elroy" ],
  517.           simpsons         =>    [ "homer", "marge", "bart" ],
  518.         );
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.      Page 8                        (printed 10/23/98)
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  533.  
  534.  
  535.  
  536.       GGGGeeeennnneeeerrrraaaattttiiiioooonnnn ooooffff    aaaa HHHHAAAASSSSHHHH OOOOFFFF LLLLIIIISSSSTTTTSSSS
  537.  
  538.        # reading from file
  539.        # flintstones: fred barney wilma dino
  540.        while ( <> )    {
  541.            next unless s/^(.*?):\s*//;
  542.            $HoL{$1}    = [ split ];
  543.        }
  544.  
  545.        # reading from file;    more temps
  546.        # flintstones: fred barney wilma dino
  547.        while ( $line = <> )    {
  548.            ($who, $rest) = split /:\s*/, $line, 2;
  549.            @fields = split ' ', $rest;
  550.            $HoL{$who} = [ @fields ];
  551.        }
  552.  
  553.        # calling a function    that returns a list
  554.        for $group (    "simpsons", "jetsons", "flintstones" ) {
  555.            $HoL{$group} = [    get_family($group) ];
  556.        }
  557.  
  558.        # likewise, but using temps
  559.        for $group (    "simpsons", "jetsons", "flintstones" ) {
  560.            @members    = get_family($group);
  561.            $HoL{$group} = [    @members ];
  562.        }
  563.  
  564.        # append new    members    to an existing family
  565.        push    @{ $HoL{"flintstones"} }, "wilma", "betty";
  566.  
  567.  
  568.       AAAAcccccccceeeessssssss aaaannnndddd PPPPrrrriiiinnnnttttiiiinnnngggg ooooffff aaaa HHHHAAAASSSSHHHH    OOOOFFFF LLLLIIIISSSSTTTTSSSS
  569.  
  570.        # one element
  571.        $HoL{flintstones}[0]    = "Fred";
  572.  
  573.        # another element
  574.        $HoL{simpsons}[1] =~    s/(\w)/\u$1/;
  575.  
  576.        # print the whole thing
  577.        foreach $family ( keys %HoL ) {
  578.            print "$family: @{ $HoL{$family}    }\n"
  579.        }
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.      Page 9                        (printed 10/23/98)
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  599.  
  600.  
  601.  
  602.        # print the whole thing with    indices
  603.        foreach $family ( keys %HoL ) {
  604.            print "family: ";
  605.            foreach $i ( 0 .. $#{ $HoL{$family} } ) {
  606.            print " $i =    $HoL{$family}[$i]";
  607.            }
  608.            print "\n";
  609.        }
  610.  
  611.        # print the whole thing sorted by number of members
  612.        foreach $family ( sort { @{$HoL{$b}}    <=> @{$HoL{$a}}    } keys %HoL ) {
  613.            print "$family: @{ $HoL{$family}    }\n"
  614.        }
  615.  
  616.        # print the whole thing sorted by number of members and name
  617.        foreach $family ( sort {
  618.                       @{$HoL{$b}} <=> @{$HoL{$a}}
  619.                           ||
  620.                           $a cmp $b
  621.               }    keys %HoL )
  622.        {
  623.            print "$family: ", join(", ", sort @{ $HoL{$family} }), "\n";
  624.        }
  625.  
  626.  
  627.      LLLLIIIISSSSTTTTSSSS OOOOFFFF HHHHAAAASSSSHHHHEEEESSSS
  628.       DDDDeeeeccccllllaaaarrrraaaattttiiiioooonnnn ooooffff aaaa LLLLIIIISSSSTTTT    OOOOFFFF HHHHAAAASSSSHHHHEEEESSSS
  629.  
  630.        @LoH    = (
  631.           {
  632.               Lead     => "fred",
  633.               Friend   => "barney",
  634.           },
  635.           {
  636.               Lead     => "george",
  637.               Wife     => "jane",
  638.               Son      => "elroy",
  639.           },
  640.           {
  641.               Lead     => "homer",
  642.               Wife     => "marge",
  643.               Son      => "bart",
  644.           }
  645.         );
  646.  
  647.  
  648.       GGGGeeeennnneeeerrrraaaattttiiiioooonnnn ooooffff    aaaa LLLLIIIISSSSTTTT OOOOFFFF HHHHAAAASSSSHHHHEEEESSSS
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.      Page 10                        (printed 10/23/98)
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  665.  
  666.  
  667.  
  668.        # reading from file
  669.        # format: LEAD=fred FRIEND=barney
  670.        while ( <> )    {
  671.            $rec = {};
  672.            for $field ( split ) {
  673.            ($key, $value) = split /=/, $field;
  674.            $rec->{$key}    = $value;
  675.            }
  676.            push @LoH, $rec;
  677.        }
  678.  
  679.        # reading from file
  680.        # format: LEAD=fred FRIEND=barney
  681.        # no    temp
  682.        while ( <> )    {
  683.            push @LoH, { split /[\s+=]/ };
  684.        }
  685.  
  686.        # calling a function     that returns a    key,value list,    like
  687.        # "lead","fred","daughter","pebbles"
  688.        while ( %fields = getnextpairset() )    {
  689.            push @LoH, { %fields };
  690.        }
  691.  
  692.        # likewise, but using no temp vars
  693.        while (<>) {
  694.            push @LoH, { parsepairs($_) };
  695.        }
  696.  
  697.        # add key/value to an element
  698.        $LoH[0]{pet}    = "dino";
  699.        $LoH[2]{pet}    = "santa's little helper";
  700.  
  701.  
  702.       AAAAcccccccceeeessssssss aaaannnndddd PPPPrrrriiiinnnnttttiiiinnnngggg ooooffff aaaa LLLLIIIISSSSTTTT    OOOOFFFF HHHHAAAASSSSHHHHEEEESSSS
  703.  
  704.        # one element
  705.        $LoH[0]{lead} = "fred";
  706.  
  707.        # another element
  708.        $LoH[1]{lead} =~ s/(\w)/\u$1/;
  709.  
  710.        # print the whole thing with    refs
  711.        for $href ( @LoH ) {
  712.            print "{    ";
  713.            for $role ( keys    %$href ) {
  714.            print "$role=$href->{$role} ";
  715.            }
  716.            print "}\n";
  717.        }
  718.  
  719.  
  720.  
  721.  
  722.  
  723.      Page 11                        (printed 10/23/98)
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  731.  
  732.  
  733.  
  734.        # print the whole thing with    indices
  735.        for $i ( 0 .. $#LoH ) {
  736.            print "$i is { ";
  737.            for $role ( keys    %{ $LoH[$i] } )    {
  738.            print "$role=$LoH[$i]{$role}    ";
  739.            }
  740.            print "}\n";
  741.        }
  742.  
  743.        # print the whole thing one at a time
  744.        for $i ( 0 .. $#LoH ) {
  745.            for $role ( keys    %{ $LoH[$i] } )    {
  746.            print "elt $i $role is $LoH[$i]{$role}\n";
  747.            }
  748.        }
  749.  
  750.  
  751.      HHHHAAAASSSSHHHHEEEESSSS OOOOFFFF HHHHAAAASSSSHHHHEEEESSSS
  752.       DDDDeeeeccccllllaaaarrrraaaattttiiiioooonnnn ooooffff aaaa HHHHAAAASSSSHHHH    OOOOFFFF HHHHAAAASSSSHHHHEEEESSSS
  753.  
  754.        %HoH    = (
  755.           flintstones => {
  756.               lead        => "fred",
  757.               pal        => "barney",
  758.           },
  759.           jetsons     => {
  760.               lead        => "george",
  761.               wife        => "jane",
  762.               "his boy" => "elroy",
  763.           },
  764.           simpsons    => {
  765.               lead        => "homer",
  766.               wife        => "marge",
  767.               kid        => "bart",
  768.           },
  769.        );
  770.  
  771.  
  772.       GGGGeeeennnneeeerrrraaaattttiiiioooonnnn ooooffff    aaaa HHHHAAAASSSSHHHH OOOOFFFF HHHHAAAASSSSHHHHEEEESSSS
  773.  
  774.        # reading from file
  775.        # flintstones: lead=fred pal=barney wife=wilma pet=dino
  776.        while ( <> )    {
  777.            next unless s/^(.*?):\s*//;
  778.            $who = $1;
  779.            for $field ( split ) {
  780.            ($key, $value) = split /=/, $field;
  781.            $HoH{$who}{$key} = $value;
  782.            }
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.      Page 12                        (printed 10/23/98)
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  797.  
  798.  
  799.  
  800.        # reading from file;    more temps
  801.        while ( <> )    {
  802.            next unless s/^(.*?):\s*//;
  803.            $who = $1;
  804.            $rec = {};
  805.            $HoH{$who} = $rec;
  806.            for $field ( split ) {
  807.            ($key, $value) = split /=/, $field;
  808.            $rec->{$key}    = $value;
  809.            }
  810.        }
  811.  
  812.        # calling a function     that returns a    key,value hash
  813.        for $group (    "simpsons", "jetsons", "flintstones" ) {
  814.            $HoH{$group} = {    get_family($group) };
  815.        }
  816.  
  817.        # likewise, but using temps
  818.        for $group (    "simpsons", "jetsons", "flintstones" ) {
  819.            %members    = get_family($group);
  820.            $HoH{$group} = {    %members };
  821.        }
  822.  
  823.        # append new    members    to an existing family
  824.        %new_folks =    (
  825.            wife => "wilma",
  826.            pet  => "dino",
  827.        );
  828.  
  829.        for $what (keys %new_folks) {
  830.            $HoH{flintstones}{$what}    = $new_folks{$what};
  831.        }
  832.  
  833.  
  834.       AAAAcccccccceeeessssssss aaaannnndddd PPPPrrrriiiinnnnttttiiiinnnngggg ooooffff aaaa HHHHAAAASSSSHHHH    OOOOFFFF HHHHAAAASSSSHHHHEEEESSSS
  835.  
  836.        # one element
  837.        $HoH{flintstones}{wife} = "wilma";
  838.  
  839.        # another element
  840.        $HoH{simpsons}{lead}    =~ s/(\w)/\u$1/;
  841.  
  842.        # print the whole thing
  843.        foreach $family ( keys %HoH ) {
  844.            print "$family: { ";
  845.            for $role ( keys    %{ $HoH{$family} } ) {
  846.            print "$role=$HoH{$family}{$role} ";
  847.            }
  848.            print "}\n";
  849.        }
  850.  
  851.  
  852.  
  853.  
  854.  
  855.      Page 13                        (printed 10/23/98)
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  863.  
  864.  
  865.  
  866.        # print the whole thing  somewhat sorted
  867.        foreach $family ( sort keys %HoH ) {
  868.            print "$family: { ";
  869.            for $role ( sort    keys %{    $HoH{$family} }    ) {
  870.            print "$role=$HoH{$family}{$role} ";
  871.            }
  872.            print "}\n";
  873.        }
  874.  
  875.        # print the whole thing sorted by number of members
  876.        foreach $family ( sort { keys %{$HoH{$b}} <=> keys %{$HoH{$a}} } keys %HoH )    {
  877.            print "$family: { ";
  878.            for $role ( sort    keys %{    $HoH{$family} }    ) {
  879.            print "$role=$HoH{$family}{$role} ";
  880.            }
  881.            print "}\n";
  882.        }
  883.  
  884.        # establish a sort order (rank) for each role
  885.        $i =    0;
  886.        for ( qw(lead wife son daughter pal pet) ) {    $rank{$_} = ++$i }
  887.  
  888.        # now print the whole thing sorted by number    of members
  889.        foreach $family ( sort { keys %{ $HoH{$b} } <=> keys    %{ $HoH{$a} } }    keys %HoH ) {
  890.            print "$family: { ";
  891.            # and print these according to rank order
  892.            for $role ( sort    { $rank{$a} <=>    $rank{$b} }  keys %{ $HoH{$family} } ) {
  893.            print "$role=$HoH{$family}{$role} ";
  894.            }
  895.            print "}\n";
  896.        }
  897.  
  898.  
  899.      MMMMOOOORRRREEEE EEEELLLLAAAABBBBOOOORRRRAAAATTTTEEEE RRRREEEECCCCOOOORRRRDDDDSSSS
  900.       DDDDeeeeccccllllaaaarrrraaaattttiiiioooonnnn ooooffff MMMMOOOORRRREEEE EEEELLLLAAAABBBBOOOORRRRAAAATTTTEEEE    RRRREEEECCCCOOOORRRRDDDDSSSS
  901.  
  902.       Here's a sample showing how to create    and use    a record whose
  903.       fields are of    many different sorts:
  904.  
  905.            $rec = {
  906.            TEXT         =>    $string,
  907.            SEQUENCE  =>    [ @old_values ],
  908.            LOOKUP    =>    { %some_table },
  909.            THATCODE  =>    \&some_function,
  910.            THISCODE  =>    sub { $_[0] ** $_[1] },
  911.            HANDLE    =>    \*STDOUT,
  912.            };
  913.  
  914.            print $rec->{TEXT};
  915.  
  916.            print $rec->{LIST}[0];
  917.            $last = pop @ { $rec->{SEQUENCE}    };
  918.  
  919.  
  920.  
  921.      Page 14                        (printed 10/23/98)
  922.  
  923.  
  924.  
  925.  
  926.  
  927.  
  928.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  929.  
  930.  
  931.  
  932.            print $rec->{LOOKUP}{"key"};
  933.            ($first_k, $first_v) = each %{ $rec->{LOOKUP} };
  934.  
  935.            $answer = $rec->{THATCODE}->($arg);
  936.            $answer = $rec->{THISCODE}->($arg1, $arg2);
  937.  
  938.            # careful of extra block    braces on fh ref
  939.            print { $rec->{HANDLE} }    "a string\n";
  940.  
  941.            use FileHandle;
  942.            $rec->{HANDLE}->autoflush(1);
  943.            $rec->{HANDLE}->print(" a string\n");
  944.  
  945.  
  946.       DDDDeeeeccccllllaaaarrrraaaattttiiiioooonnnn ooooffff aaaa HHHHAAAASSSSHHHH    OOOOFFFF CCCCOOOOMMMMPPPPLLLLEEEEXXXX RRRREEEECCCCOOOORRRRDDDDSSSS
  947.  
  948.            %TV = (
  949.           flintstones => {
  950.               series   => "flintstones",
  951.               nights   => [ qw(monday thursday friday) ],
  952.               members  => [
  953.               { name => "fred",    role => "lead", age  => 36, },
  954.               { name => "wilma",   role => "wife", age  => 31, },
  955.               { name => "pebbles", role => "kid",  age  =>    4, },
  956.               ],
  957.           },
  958.  
  959.           jetsons     => {
  960.               series   => "jetsons",
  961.               nights   => [ qw(wednesday saturday) ],
  962.               members  => [
  963.               { name => "george",  role => "lead", age  => 41, },
  964.               { name => "jane",    role => "wife", age  => 39, },
  965.               { name => "elroy",   role => "kid",  age  =>    9, },
  966.               ],
  967.            },
  968.  
  969.           simpsons    => {
  970.               series   => "simpsons",
  971.               nights   => [ qw(monday) ],
  972.               members  => [
  973.               { name => "homer", role => "lead", age  => 34, },
  974.               { name => "marge", role => "wife", age => 37,    },
  975.               { name => "bart",  role => "kid",  age  =>  11, },
  976.               ],
  977.            },
  978.         );
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.      Page 15                        (printed 10/23/98)
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  995.  
  996.  
  997.  
  998.       GGGGeeeennnneeeerrrraaaattttiiiioooonnnn ooooffff    aaaa HHHHAAAASSSSHHHH OOOOFFFF CCCCOOOOMMMMPPPPLLLLEEEEXXXX RRRREEEECCCCOOOORRRRDDDDSSSS
  999.  
  1000.            # reading from file
  1001.            # this is most easily done by having the    file itself be
  1002.            # in the    raw data format    as shown above.     perl is happy
  1003.            # to parse complex data structures if declared as data, so
  1004.            # sometimes it's    easiest    to do that
  1005.  
  1006.            # here's    a piece    by piece build up
  1007.            $rec = {};
  1008.            $rec->{series} =    "flintstones";
  1009.            $rec->{nights} =    [ find_days() ];
  1010.  
  1011.            @members    = ();
  1012.            # assume    this file in field=value syntax
  1013.            while (<>) {
  1014.            %fields = split /[\s=]+/;
  1015.            push    @members, { %fields };
  1016.            }
  1017.            $rec->{members} = [ @members ];
  1018.  
  1019.            # now remember the whole    thing
  1020.            $TV{ $rec->{series} } = $rec;
  1021.  
  1022.            ###########################################################
  1023.            # now, you might    want to    make interesting extra fields that
  1024.            # include pointers back into the    same data structure so if
  1025.            # change    one piece, it changes everywhere, like for examples
  1026.            # if you    wanted a {kids}    field that was an array    reference
  1027.            # to a list of the kids'    records    without    having duplicate
  1028.            # records and thus update problems.
  1029.            ###########################################################
  1030.            foreach $family (keys %TV) {
  1031.            $rec    = $TV{$family};    # temp pointer
  1032.            @kids = ();
  1033.            for $person ( @{ $rec->{members} } )    {
  1034.                if ($person->{role} =~ /kid|son|daughter/) {
  1035.                push    @kids, $person;
  1036.                }
  1037.            }
  1038.            # REMEMBER: $rec and    $TV{$family} point to same data!!
  1039.            $rec->{kids}    = [ @kids ];
  1040.            }
  1041.  
  1042.            # you copied the    list, but the list itself contains pointers
  1043.            # to uncopied objects. this means that if you make bart get
  1044.            # older via
  1045.  
  1046.            $TV{simpsons}{kids}[0]{age}++;
  1047.  
  1048.            # then this would also change in
  1049.            print $TV{simpsons}{members}[2]{age};
  1050.  
  1051.  
  1052.  
  1053.      Page 16                        (printed 10/23/98)
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  1061.  
  1062.  
  1063.  
  1064.            # because $TV{simpsons}{kids}[0]    and $TV{simpsons}{members}[2]
  1065.            # both point to the same    underlying anonymous hash table
  1066.  
  1067.            # print the whole thing
  1068.            foreach $family ( keys %TV ) {
  1069.            print "the $family";
  1070.            print " is on during    @{ $TV{$family}{nights}    }\n";
  1071.            print "its members are:\n";
  1072.            for $who ( @{ $TV{$family}{members} } ) {
  1073.                print " $who->{name} ($who->{role}), age    $who->{age}\n";
  1074.            }
  1075.            print "it turns out that $TV{$family}{lead} has ";
  1076.            print scalar    ( @{ $TV{$family}{kids}    } ), " kids named ";
  1077.            print join (", ", map { $_->{name} }    @{ $TV{$family}{kids} }    );
  1078.            print "\n";
  1079.            }
  1080.  
  1081.  
  1082.      DDDDaaaattttaaaabbbbaaaasssseeee TTTTiiiieeeessss
  1083.       You cannot easily tie    a multilevel data structure (such as a
  1084.       hash of hashes) to a dbm file.  The first problem is that
  1085.       all but GDBM and Berkeley DB have size limitations, but
  1086.       beyond that, you also    have problems with how references are
  1087.       to be    represented on disk.  One experimental module that
  1088.       does partially attempt to address this need is the MLDBM
  1089.       module.  Check your nearest CPAN site    as described in    the
  1090.       _p_e_r_l_m_o_d_l_i_b manpage for source    code to    MLDBM.
  1091.  
  1092.      SSSSEEEEEEEE AAAALLLLSSSSOOOO
  1093.       _p_e_r_l_r_e_f(1), _p_e_r_l_l_o_l(1), _p_e_r_l_d_a_t_a(1), _p_e_r_l_o_b_j(1)
  1094.  
  1095.      AAAAUUUUTTTTHHHHOOOORRRR
  1096.       Tom Christiansen <_t_c_h_r_i_s_t@_p_e_r_l._c_o_m>
  1097.  
  1098.       Last update:    Wed Oct    23 04:57:50 MET    DST 1996
  1099.  
  1100.  
  1101.  
  1102.  
  1103.  
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.      Page 17                        (printed 10/23/98)
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.      PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))         22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222))))        PPPPEEEERRRRLLLLDDDDSSSSCCCC((((1111))))
  1127.  
  1128.  
  1129.  
  1130.  
  1131.  
  1132.  
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.      Page 18                        (printed 10/23/98)
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.